

<!DOCTYPE html>
<!--[if IE]><![endif]-->
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <title>Testing Flux Applications - React Blog</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta property="og:title" content="Testing Flux Applications - React Blog">
  <meta property="og:type" content="article">
  <meta property="og:url" content="https://facebook.github.io/react/blog/2014/09/24/testing-flux-applications.html">
  <meta property="og:image" content="https://facebook.github.io/react/img/logo_og.png">
  <meta property="og:description" content="A more up-to-date version of this post is available as part of the Flux documentation.
">
  <meta property="fb:app_id" content="623268441017527">

  <link rel="shortcut icon" href="/favicon.ico">
  <link rel="alternate" type="application/rss+xml" title="React" href="https://facebook.github.io/react/feed.xml">

  <link rel="stylesheet" href="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.css" />
  <link rel="stylesheet" href="/css/syntax.css">
  <link rel="stylesheet" href="/css/codemirror.css">
  <link rel="stylesheet" href="/css/react.css">

  <script src="//use.typekit.net/vqa1hcx.js"></script>
  <script>try{Typekit.load();}catch(e){}</script>

  <!--[if lte IE 8]>
  <script src="/js/html5shiv.min.js"></script>
  <script src="/js/es5-shim.min.js"></script>
  <script src="/js/es5-sham.min.js"></script>
  <![endif]-->
  <script type="text/javascript" src="https://cdn.jsdelivr.net/docsearch.js/1/docsearch.min.js"></script>
  <script src="/js/codemirror.js"></script>
  <script src="/js/javascript.js"></script>
  <script src="/js/xml.js"></script>
  <script src="/js/jsx.js"></script>
  <script src="/js/react.js"></script>
  <script src="/js/react-dom.js"></script>
  <script src="/js/babel.min.js"></script>
  <script src="/js/live_editor.js"></script>
</head>
<body>

  <div class="container">

    <div class="nav-main">
  <div class="wrap">
    <a class="nav-home" href="/">
      <img class="nav-logo" src="/img/logo.svg" width="36" height="36">
      React
    </a>
    <div class="nav-lists">
      <ul class="nav-site nav-site-internal">
        <li><a href="/docs/hello-world.html">Docs</a></li>
        <li><a href="/tutorial/tutorial.html">Tutorial</a></li>
        <li><a href="/community/support.html">Community</a></li>
        <li><a href="/blog/" class="active">Blog</a></li>
        <li class="nav-site-search">
          <input id="algolia-doc-search" type="text" placeholder="Search docs..." />
        </li>
      </ul>
      <ul class="nav-site nav-site-external">
        <li><a href="https://github.com/facebook/react">GitHub</a></li>
        <li><a href="https://github.com/facebook/react/releases">v16.0.0-alpha.3</a></li>
      </ul>
    </div>
  </div>
</div>


    <section class="content wrap blogContent">

  <div class="inner-content">
    

<h1>

  Testing Flux Applications

</h1>

<p class="meta">
  September 24, 2014
  by
  
    
      <a href="https://twitter.com/fisherwebdev">Bill Fisher</a>
    
    
  
</p>

<hr>

<div class="post">
  <p><strong>A more up-to-date version of this post is available as part of the <a href="https://facebook.github.io/flux/docs/testing-flux-applications.html">Flux documentation</a>.</strong></p>

<p><a href="https://facebook.github.io/flux/">Flux</a> is the application architecture that Facebook uses to build web applications with <a href="/">React</a>. It&#39;s based on a unidirectional data flow. In previous blog posts and documentation articles, we&#39;ve shown the <a href="https://facebook.github.io/flux/docs/overview.html">basic structure and data flow</a>, more closely examined the <a href="/blog/2014/07/30/flux-actions-and-the-dispatcher.html">dispatcher and action creators</a>, and shown how to put it all together with a <a href="https://facebook.github.io/flux/docs/todo-list.html">tutorial</a>. Now let&#39;s look at how to do formal unit testing of Flux applications with <a href="https://facebook.github.io/jest/">Jest</a>, Facebook&#39;s auto-mocking testing framework.</p>

<h2>Testing with Jest</h2>

<p>For a unit test to operate on a truly isolated <em>unit</em> of the application, we need to mock every module except the one we are testing. Jest makes the mocking of other parts of a Flux application trivial. To illustrate testing with Jest, we&#39;ll return to our <a href="https://github.com/facebook/flux/tree/master/examples/flux-todomvc">example TodoMVC application</a>.</p>

<p>The first steps toward working with Jest are as follows:</p>

<ol>
<li>Get the module dependencies for the application installed by running <code>npm install</code>.</li>
<li>Create a directory <code>__tests__/</code> with a test file, in this case TodoStore-test.js</li>
<li>Run <code>npm install jest-cli —save-dev</code></li>
<li>Add the following to your package.json</li>
</ol>
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="p">{</span>
  <span class="p">...</span>
  <span class="s2">&quot;scripts&quot;</span><span class="o">:</span> <span class="p">{</span>
    <span class="s2">&quot;test&quot;</span><span class="o">:</span> <span class="s2">&quot;jest&quot;</span>
  <span class="p">}</span>
  <span class="p">...</span>
<span class="p">}</span>
</code></pre></div>
<p>Now you&#39;re ready to run your tests from the command line with <code>npm test</code>.</p>

<p>By default, all modules are mocked, so the only boilerplate we need in TodoStore-test.js is a declarative call to Jest&#39;s <code>dontMock()</code> method.</p>
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">jest</span><span class="p">.</span><span class="nx">dontMock</span><span class="p">(</span><span class="s1">&#39;TodoStore&#39;</span><span class="p">);</span>
</code></pre></div>
<p>This tells Jest to let TodoStore be a real object with real, live methods. Jest will mock all other objects involved with the test.</p>

<h2>Testing Stores</h2>

<p>At Facebook, Flux stores often receive a great deal of formal unit test coverage, as this is where the application state and logic lives. Stores are arguably the most important place in a Flux application to provide coverage, but at first glance, it&#39;s not entirely obvious how to test them.</p>

<p>By design, stores can&#39;t be modified from the outside. They have no setters. The only way new data can enter a store is through the callback it registers with the dispatcher.</p>

<p>We therefore need to simulate the Flux data flow with this <em>one weird trick</em>.</p>
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">mockRegister</span> <span class="o">=</span> <span class="nx">MyDispatcher</span><span class="p">.</span><span class="nx">register</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">mockRegisterInfo</span> <span class="o">=</span> <span class="nx">mockRegister</span><span class="p">.</span><span class="nx">mock</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">callsToRegister</span> <span class="o">=</span> <span class="nx">mockRegisterInfo</span><span class="p">.</span><span class="nx">calls</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">firstCall</span> <span class="o">=</span> <span class="nx">callsToRegister</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
<span class="kd">var</span> <span class="nx">firstArgument</span> <span class="o">=</span> <span class="nx">firstCall</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
<span class="kd">var</span> <span class="nx">callback</span> <span class="o">=</span> <span class="nx">firstArgument</span><span class="p">;</span>
</code></pre></div>
<p>We now have the store&#39;s registered callback, the sole mechanism by which data can enter the store.</p>

<p>For folks new to Jest, or mocks in general, it might not be entirely obvious what is happening in that code block, so let&#39;s look at each part of it a bit more closely. We start out by looking at the <code>register()</code> method of our application&#39;s dispatcher — the method that the store uses to register its callback with the dispatcher. The dispatcher has been thoroughly mocked automatically by Jest, so we can get a reference to the mocked version of the <code>register()</code> method just as we would normally refer to that method in our production code. But we can get additional information about that method with the <code>mock</code> <em>property</em> of that method. We don&#39;t often think of methods having properties, but in Jest, this idea is vital. Every method of a mocked object has this property, and it allows us to examine how the method is being called during the test. A chronologically ordered list of calls to <code>register()</code> is available with the <code>calls</code> property of <code>mock</code>, and each of these calls has a list of the arguments that were used in each method call.</p>

<p>So in this code, we are really saying, &quot;Give me a reference to the first argument of the first call to MyDispatcher&#39;s <code>register()</code> method.&quot; That first argument is the store&#39;s callback, so now we have all we need to start testing.  But first, we can save ourselves some semicolons and roll all of this into a single line:</p>
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">callback</span> <span class="o">=</span> <span class="nx">MyDispatcher</span><span class="p">.</span><span class="nx">register</span><span class="p">.</span><span class="nx">mock</span><span class="p">.</span><span class="nx">calls</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">];</span>
</code></pre></div>
<p>We can invoke that callback whenever we like, independent of our application&#39;s dispatcher or action creators. We will, in fact, fake the behavior of the dispatcher and action creators by invoking the callback with an action that we&#39;ll create directly in our test.</p>
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">payload</span> <span class="o">=</span> <span class="p">{</span>
  <span class="nx">source</span><span class="o">:</span> <span class="s1">&#39;VIEW_ACTION&#39;</span><span class="p">,</span>
  <span class="nx">action</span><span class="o">:</span> <span class="p">{</span>
    <span class="nx">actionType</span><span class="o">:</span> <span class="nx">TodoConstants</span><span class="p">.</span><span class="nx">TODO_CREATE</span><span class="p">,</span>
    <span class="nx">text</span><span class="o">:</span> <span class="s1">&#39;foo&#39;</span>
  <span class="p">}</span>
<span class="p">};</span>
<span class="nx">callback</span><span class="p">(</span><span class="nx">payload</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">all</span> <span class="o">=</span> <span class="nx">TodoStore</span><span class="p">.</span><span class="nx">getAll</span><span class="p">();</span>
<span class="kd">var</span> <span class="nx">keys</span> <span class="o">=</span> <span class="nb">Object</span><span class="p">.</span><span class="nx">keys</span><span class="p">(</span><span class="nx">all</span><span class="p">);</span>
<span class="nx">expect</span><span class="p">(</span><span class="nx">all</span><span class="p">[</span><span class="nx">keys</span><span class="p">[</span><span class="mi">0</span><span class="p">]].</span><span class="nx">text</span><span class="p">).</span><span class="nx">toEqual</span><span class="p">(</span><span class="s1">&#39;foo&#39;</span><span class="p">);</span>
</code></pre></div>
<h2>Putting it All Together</h2>

<p>The example Flux TodoMVC application has been updated with an example test for the TodoStore, but let&#39;s look at an abbreviated version of the entire test. The most important things to notice in this test are how we keep a reference to the store&#39;s registered callback in the closure of the test, and how we recreate the store before every test so that we clear the state of the store entirely.</p>
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">jest</span><span class="p">.</span><span class="nx">dontMock</span><span class="p">(</span><span class="s1">&#39;../TodoStore&#39;</span><span class="p">);</span>
<span class="nx">jest</span><span class="p">.</span><span class="nx">dontMock</span><span class="p">(</span><span class="s1">&#39;react/lib/merge&#39;</span><span class="p">);</span>

<span class="nx">describe</span><span class="p">(</span><span class="s1">&#39;TodoStore&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>

  <span class="kd">var</span> <span class="nx">TodoConstants</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;../../constants/TodoConstants&#39;</span><span class="p">);</span>

  <span class="c1">// mock actions inside dispatch payloads</span>
  <span class="kd">var</span> <span class="nx">actionTodoCreate</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">source</span><span class="o">:</span> <span class="s1">&#39;VIEW_ACTION&#39;</span><span class="p">,</span>
    <span class="nx">action</span><span class="o">:</span> <span class="p">{</span>
      <span class="nx">actionType</span><span class="o">:</span> <span class="nx">TodoConstants</span><span class="p">.</span><span class="nx">TODO_CREATE</span><span class="p">,</span>
      <span class="nx">text</span><span class="o">:</span> <span class="s1">&#39;foo&#39;</span>
    <span class="p">}</span>
  <span class="p">};</span>
  <span class="kd">var</span> <span class="nx">actionTodoDestroy</span> <span class="o">=</span> <span class="p">{</span>
    <span class="nx">source</span><span class="o">:</span> <span class="s1">&#39;VIEW_ACTION&#39;</span><span class="p">,</span>
    <span class="nx">action</span><span class="o">:</span> <span class="p">{</span>
      <span class="nx">actionType</span><span class="o">:</span> <span class="nx">TodoConstants</span><span class="p">.</span><span class="nx">TODO_DESTROY</span><span class="p">,</span>
      <span class="nx">id</span><span class="o">:</span> <span class="s1">&#39;replace me in test&#39;</span>
    <span class="p">}</span>
  <span class="p">};</span>

  <span class="kd">var</span> <span class="nx">AppDispatcher</span><span class="p">;</span>
  <span class="kd">var</span> <span class="nx">TodoStore</span><span class="p">;</span>
  <span class="kd">var</span> <span class="nx">callback</span><span class="p">;</span>

  <span class="nx">beforeEach</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="nx">AppDispatcher</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;../../dispatcher/AppDispatcher&#39;</span><span class="p">);</span>
    <span class="nx">TodoStore</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;../TodoStore&#39;</span><span class="p">);</span>
    <span class="nx">callback</span> <span class="o">=</span> <span class="nx">AppDispatcher</span><span class="p">.</span><span class="nx">register</span><span class="p">.</span><span class="nx">mock</span><span class="p">.</span><span class="nx">calls</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="mi">0</span><span class="p">];</span>
  <span class="p">});</span>

  <span class="nx">it</span><span class="p">(</span><span class="s1">&#39;registers a callback with the dispatcher&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="nx">expect</span><span class="p">(</span><span class="nx">AppDispatcher</span><span class="p">.</span><span class="nx">register</span><span class="p">.</span><span class="nx">mock</span><span class="p">.</span><span class="nx">calls</span><span class="p">.</span><span class="nx">length</span><span class="p">).</span><span class="nx">toBe</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
  <span class="p">});</span>

  <span class="nx">it</span><span class="p">(</span><span class="s1">&#39;initializes with no to-do items&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="kd">var</span> <span class="nx">all</span> <span class="o">=</span> <span class="nx">TodoStore</span><span class="p">.</span><span class="nx">getAll</span><span class="p">();</span>
    <span class="nx">expect</span><span class="p">(</span><span class="nx">all</span><span class="p">).</span><span class="nx">toEqual</span><span class="p">({});</span>
  <span class="p">});</span>

  <span class="nx">it</span><span class="p">(</span><span class="s1">&#39;creates a to-do item&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="nx">callback</span><span class="p">(</span><span class="nx">actionTodoCreate</span><span class="p">);</span>
    <span class="kd">var</span> <span class="nx">all</span> <span class="o">=</span> <span class="nx">TodoStore</span><span class="p">.</span><span class="nx">getAll</span><span class="p">();</span>
    <span class="kd">var</span> <span class="nx">keys</span> <span class="o">=</span> <span class="nb">Object</span><span class="p">.</span><span class="nx">keys</span><span class="p">(</span><span class="nx">all</span><span class="p">);</span>
    <span class="nx">expect</span><span class="p">(</span><span class="nx">keys</span><span class="p">.</span><span class="nx">length</span><span class="p">).</span><span class="nx">toBe</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
    <span class="nx">expect</span><span class="p">(</span><span class="nx">all</span><span class="p">[</span><span class="nx">keys</span><span class="p">[</span><span class="mi">0</span><span class="p">]].</span><span class="nx">text</span><span class="p">).</span><span class="nx">toEqual</span><span class="p">(</span><span class="s1">&#39;foo&#39;</span><span class="p">);</span>
  <span class="p">});</span>

  <span class="nx">it</span><span class="p">(</span><span class="s1">&#39;destroys a to-do item&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="nx">callback</span><span class="p">(</span><span class="nx">actionTodoCreate</span><span class="p">);</span>
    <span class="kd">var</span> <span class="nx">all</span> <span class="o">=</span> <span class="nx">TodoStore</span><span class="p">.</span><span class="nx">getAll</span><span class="p">();</span>
    <span class="kd">var</span> <span class="nx">keys</span> <span class="o">=</span> <span class="nb">Object</span><span class="p">.</span><span class="nx">keys</span><span class="p">(</span><span class="nx">all</span><span class="p">);</span>
    <span class="nx">expect</span><span class="p">(</span><span class="nx">keys</span><span class="p">.</span><span class="nx">length</span><span class="p">).</span><span class="nx">toBe</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
    <span class="nx">actionTodoDestroy</span><span class="p">.</span><span class="nx">action</span><span class="p">.</span><span class="nx">id</span> <span class="o">=</span> <span class="nx">keys</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
    <span class="nx">callback</span><span class="p">(</span><span class="nx">actionTodoDestroy</span><span class="p">);</span>
    <span class="nx">expect</span><span class="p">(</span><span class="nx">all</span><span class="p">[</span><span class="nx">keys</span><span class="p">[</span><span class="mi">0</span><span class="p">]]).</span><span class="nx">toBeUndefined</span><span class="p">();</span>
  <span class="p">});</span>

<span class="p">});</span>
</code></pre></div>
<p>You can take a look at all this code in the <a href="https://github.com/facebook/flux/tree/master/examples/flux-todomvc/js/stores/__tests__/TodoStore-test.js">TodoStore&#39;s tests on GitHub</a> as well. </p>

<h2>Mocking Data Derived from Other Stores</h2>

<p>Sometimes our stores rely on data from other stores. Because all of our modules are mocked, we&#39;ll need to simulate the data that comes from the other store.  We can do this by retrieving the mock function and adding a custom return value to it.</p>
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">MyOtherStore</span> <span class="o">=</span> <span class="nx">require</span><span class="p">(</span><span class="s1">&#39;../MyOtherStore&#39;</span><span class="p">);</span>
<span class="nx">MyOtherStore</span><span class="p">.</span><span class="nx">getState</span><span class="p">.</span><span class="nx">mockReturnValue</span><span class="p">({</span>
  <span class="s1">&#39;123&#39;</span><span class="o">:</span> <span class="p">{</span>
    <span class="nx">id</span><span class="o">:</span> <span class="s1">&#39;123&#39;</span><span class="p">,</span>
    <span class="nx">text</span><span class="o">:</span> <span class="s1">&#39;foo&#39;</span>
  <span class="p">},</span>
  <span class="s1">&#39;456&#39;</span><span class="o">:</span> <span class="p">{</span>
    <span class="nx">id</span><span class="o">:</span> <span class="s1">&#39;456&#39;</span><span class="p">,</span>
    <span class="nx">text</span><span class="o">:</span> <span class="s1">&#39;bar&#39;</span>
  <span class="p">}</span>
<span class="p">});</span>
</code></pre></div>
<p>Now we have a collection of objects that will come back from MyOtherStore whenever we call MyOtherStore.getState() in our tests.  Any application state can be simulated with a combination of these custom return values and the previously shown technique of working with the store&#39;s registered callback.</p>

<p>A brief example of this technique is up on GitHub within the Flux Chat example&#39;s <a href="https://github.com/facebook/flux/tree/master/examples/flux-chat/js/stores/__tests__/UnreadThreadStore-test.js">UnreadThreadStore-test.js</a>.</p>

<p>For more information about the <code>mock</code> property of mocked methods or Jest&#39;s ability to provide custom mock values, see Jest&#39;s documentation on <a href="https://facebook.github.io/jest/docs/mock-functions.html">mock functions</a>.</p>

<h2>Moving Logic from React to Stores</h2>

<p>What often starts as a little piece of seemingly benign logic in our React components often presents a problem while creating unit tests. We want to be able to write tests that read like a specification for our application&#39;s behavior, and when application logic slips into our view layer, this becomes more difficult.</p>

<p>For example, when a user has marked each of their to-do items as complete, the TodoMVC specification dictates that we should also change the status of the &quot;Mark all as complete&quot; checkbox automatically. To create that logic, we might be tempted to write code like this in our MainSection&#39;s <code>render()</code> method:</p>
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">var</span> <span class="nx">allTodos</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">allTodos</span><span class="p">;</span>
<span class="kd">var</span> <span class="nx">allChecked</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">id</span> <span class="k">in</span> <span class="nx">allTodos</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">allTodos</span><span class="p">[</span><span class="nx">id</span><span class="p">].</span><span class="nx">complete</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">allChecked</span> <span class="o">=</span> <span class="kc">false</span><span class="p">;</span>
    <span class="k">break</span><span class="p">;</span>
  <span class="p">}</span>
<span class="p">}</span>
<span class="p">...</span>

<span class="k">return</span> <span class="p">(</span>
  <span class="o">&lt;</span><span class="nx">section</span> <span class="nx">id</span><span class="o">=</span><span class="s2">&quot;main&quot;</span><span class="o">&gt;</span>
  <span class="o">&lt;</span><span class="nx">input</span>
    <span class="nx">id</span><span class="o">=</span><span class="s2">&quot;toggle-all&quot;</span>
    <span class="nx">type</span><span class="o">=</span><span class="s2">&quot;checkbox&quot;</span>
    <span class="nx">checked</span><span class="o">=</span><span class="p">{</span><span class="nx">allChecked</span> <span class="o">?</span> <span class="s1">&#39;checked&#39;</span> <span class="o">:</span> <span class="s1">&#39;&#39;</span><span class="p">}</span>
  <span class="o">/&gt;</span>
  <span class="p">...</span>
  <span class="o">&lt;</span><span class="err">/section&gt;</span>
<span class="p">);</span>
</code></pre></div>
<p>While this seems like an easy, normal thing to do, this is an example of application logic slipping into the views, and it can&#39;t be described in our spec-style TodoStore test. Let&#39;s take that logic and move it to the store. First, we&#39;ll create a public method on the store that will encapsulate that logic:</p>
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">areAllComplete</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
  <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">id</span> <span class="k">in</span> <span class="nx">_todos</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">_todos</span><span class="p">[</span><span class="nx">id</span><span class="p">].</span><span class="nx">complete</span><span class="p">)</span> <span class="p">{</span>
      <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
    <span class="p">}</span>
  <span class="p">}</span>
  <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
<span class="p">},</span>
</code></pre></div>
<p>Now we have the application logic where it belongs, and we can write the following test:</p>
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">it</span><span class="p">(</span><span class="s1">&#39;determines whether all to-do items are complete&#39;</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
  <span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
  <span class="k">for</span> <span class="p">(;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="mi">3</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">callback</span><span class="p">(</span><span class="nx">mockTodoCreate</span><span class="p">);</span>
  <span class="p">}</span>
  <span class="nx">expect</span><span class="p">(</span><span class="nx">TodoStore</span><span class="p">.</span><span class="nx">areAllComplete</span><span class="p">()).</span><span class="nx">toBe</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>

  <span class="kd">var</span> <span class="nx">all</span> <span class="o">=</span> <span class="nx">TodoStore</span><span class="p">.</span><span class="nx">getAll</span><span class="p">();</span>
  <span class="k">for</span> <span class="p">(</span><span class="nx">key</span> <span class="k">in</span> <span class="nx">all</span><span class="p">)</span> <span class="p">{</span>
    <span class="nx">callback</span><span class="p">({</span>
      <span class="nx">source</span><span class="o">:</span> <span class="s1">&#39;VIEW_ACTION&#39;</span><span class="p">,</span>
      <span class="nx">action</span><span class="o">:</span> <span class="p">{</span>
        <span class="nx">actionType</span><span class="o">:</span> <span class="nx">TodoConstants</span><span class="p">.</span><span class="nx">TODO_COMPLETE</span><span class="p">,</span>
        <span class="nx">id</span><span class="o">:</span> <span class="nx">key</span>
      <span class="p">}</span>
    <span class="p">});</span>
  <span class="p">}</span>
  <span class="nx">expect</span><span class="p">(</span><span class="nx">TodoStore</span><span class="p">.</span><span class="nx">areAllComplete</span><span class="p">()).</span><span class="nx">toBe</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>

  <span class="nx">callback</span><span class="p">({</span>
    <span class="nx">source</span><span class="o">:</span> <span class="s1">&#39;VIEW_ACTION&#39;</span><span class="p">,</span>
    <span class="nx">action</span><span class="o">:</span> <span class="p">{</span>
      <span class="nx">actionType</span><span class="o">:</span> <span class="nx">TodoConstants</span><span class="p">.</span><span class="nx">TODO_UNDO_COMPLETE</span><span class="p">,</span>
      <span class="nx">id</span><span class="o">:</span> <span class="nx">key</span>
    <span class="p">}</span>
  <span class="p">});</span>
  <span class="nx">expect</span><span class="p">(</span><span class="nx">TodoStore</span><span class="p">.</span><span class="nx">areAllComplete</span><span class="p">()).</span><span class="nx">toBe</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>
<span class="p">});</span>
</code></pre></div>
<p>Finally, we revise our view layer. We&#39;ll call for that data in the controller-view, TodoApp.js, and pass it down to the MainSection component.</p>
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="kd">function</span> <span class="nx">getTodoState</span><span class="p">()</span> <span class="p">{</span>
  <span class="k">return</span> <span class="p">{</span>
    <span class="nx">allTodos</span><span class="o">:</span> <span class="nx">TodoStore</span><span class="p">.</span><span class="nx">getAll</span><span class="p">(),</span>
    <span class="nx">areAllComplete</span><span class="o">:</span> <span class="nx">TodoStore</span><span class="p">.</span><span class="nx">areAllComplete</span><span class="p">()</span>
  <span class="p">};</span>
<span class="p">}</span>

<span class="kd">var</span> <span class="nx">TodoApp</span> <span class="o">=</span> <span class="nx">React</span><span class="p">.</span><span class="nx">createClass</span><span class="p">({</span>
<span class="p">...</span>

  <span class="cm">/**</span>
<span class="cm">   * @return {object}</span>
<span class="cm">   */</span>
  <span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">return</span> <span class="p">(</span>
      <span class="p">...</span>
      <span class="o">&lt;</span><span class="nx">MainSection</span>
        <span class="nx">allTodos</span><span class="o">=</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">allTodos</span><span class="p">}</span>
        <span class="nx">areAllComplete</span><span class="o">=</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">state</span><span class="p">.</span><span class="nx">areAllComplete</span><span class="p">}</span>
      <span class="o">/&gt;</span>
      <span class="p">...</span>
    <span class="p">);</span>
  <span class="p">},</span>

  <span class="cm">/**</span>
<span class="cm">   * Event handler for &#39;change&#39; events coming from the TodoStore</span>
<span class="cm">   */</span>
  <span class="nx">_onChange</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">this</span><span class="p">.</span><span class="nx">setState</span><span class="p">(</span><span class="nx">getTodoState</span><span class="p">());</span>
  <span class="p">}</span>

<span class="p">});</span>
</code></pre></div>
<p>And then we&#39;ll utilize that property for the rendering of the checkbox.</p>
<div class="highlight"><pre><code class="language-javascript" data-lang="javascript"><span class="nx">render</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
  <span class="p">...</span>

  <span class="k">return</span> <span class="p">(</span>
    <span class="o">&lt;</span><span class="nx">section</span> <span class="nx">id</span><span class="o">=</span><span class="s2">&quot;main&quot;</span><span class="o">&gt;</span>
    <span class="o">&lt;</span><span class="nx">input</span>
      <span class="nx">id</span><span class="o">=</span><span class="s2">&quot;toggle-all&quot;</span>
      <span class="nx">type</span><span class="o">=</span><span class="s2">&quot;checkbox&quot;</span>
      <span class="nx">checked</span><span class="o">=</span><span class="p">{</span><span class="k">this</span><span class="p">.</span><span class="nx">props</span><span class="p">.</span><span class="nx">areAllComplete</span> <span class="o">?</span> <span class="s1">&#39;checked&#39;</span> <span class="o">:</span> <span class="s1">&#39;&#39;</span><span class="p">}</span>
    <span class="o">/&gt;</span>
    <span class="p">...</span>
    <span class="o">&lt;</span><span class="err">/section&gt;</span>
  <span class="p">);</span>
<span class="p">},</span>
</code></pre></div>
<p>To learn how to test React components themselves, check out the <a href="https://facebook.github.io/jest/docs/tutorial-react.html">Jest tutorial for React</a> and the <a href="/docs/test-utils.html">ReactTestUtils documentation</a>.</p>

<h2>Further Reading</h2>

<ul>
<li><a href="http://martinfowler.com/articles/mocksArentStubs.html">Mocks Aren&#39;t Stubs</a> by Martin Fowler</li>
<li><a href="https://facebook.github.io/jest/docs/api.html">Jest API Reference</a></li>
</ul>

</div>


  <div class="fb-like" data-send="true" data-width="650" data-show-faces="false"></div>


  </div>
  <div class="nav-docs nav-blog">
  <div class="nav-docs-section">
    <h3>Recent posts</h3>
    <ul>
      
        <li><a href="/blog/2016/11/16/react-v15.4.0.html">React v15.4.0</a></li>
      
        <li><a href="/blog/2016/09/28/our-first-50000-stars.html">Our First 50,000 Stars</a></li>
      
        <li><a href="/blog/2016/08/05/relay-state-of-the-state.html">Relay: State of the State</a></li>
      
        <li><a href="/blog/2016/07/22/create-apps-with-no-configuration.html">Create Apps with No Configuration</a></li>
      
        <li><a href="/blog/2016/07/13/mixins-considered-harmful.html">Mixins Considered Harmful</a></li>
      
        <li><a href="/blog/2016/07/11/introducing-reacts-error-code-system.html">Introducing React's Error Code System</a></li>
      
        <li><a href="/blog/2016/04/08/react-v15.0.1.html">React v15.0.1</a></li>
      
        <li><a href="/blog/2016/04/07/react-v15.html">React v15.0</a></li>
      
        <li><a href="/blog/2016/03/29/react-v0.14.8.html">React v0.14.8</a></li>
      
        <li><a href="/blog/2016/03/16/react-v15-rc2.html">React v15.0 Release Candidate 2</a></li>
      
      <li><a href="/blog/all.html">All posts ...</a></li>
    </ul>
  </div>
</div>

</section>


    <footer class="nav-footer">
  <section class="sitemap">
    <a href="/" class="nav-home">
    </a>
    <div>
      <h5><a href="/docs/">Docs</a></h5>
      <a href="/docs/hello-world.html">Quick Start</a>
      <a href="/docs/thinking-in-react.html">Thinking in React</a>
      <a href="/tutorial/tutorial.html">Tutorial</a>
      <a href="/docs/jsx-in-depth.html">Advanced Guides</a>
    </div>
    <div>
      <h5><a href="/community/support.html">Community</a></h5>
      <a href="http://stackoverflow.com/questions/tagged/reactjs" target="_blank">Stack Overflow</a>
      <a href="https://discuss.reactjs.org/" target="_blank">Discussion Forum</a>
      <a href="https://discord.gg/0ZcbPKXt5bZjGY5n" target="_blank">Reactiflux Chat</a>
      <a href="https://www.facebook.com/react" target="_blank">Facebook</a>
      <a href="https://twitter.com/reactjs" target="_blank">Twitter</a>
    </div>
    <div>
      <h5><a href="/community/support.html">Resources</a></h5>
      <a href="/community/conferences.html">Conferences</a>
      <a href="/community/videos.html">Videos</a>
      <a href="https://github.com/facebook/react/wiki/Examples" target="_blank">Examples</a>
      <a href="https://github.com/facebook/react/wiki/Complementary-Tools" target="_blank">Complementary Tools</a>
    </div>
    <div>
      <h5>More</h5>
      <a href="/blog/">Blog</a>
      <a href="https://github.com/facebook/react" target="_blank">GitHub</a>
      <a href="http://facebook.github.io/react-native/" target="_blank">React Native</a>
      <a href="/acknowledgements.html">Acknowledgements</a>
    </div>
  </section>
  <a href="https://code.facebook.com/projects/" target="_blank" class="fbOpenSource">
    <img src="/img/oss_logo.png" alt="Facebook Open Source" width="170" height="45"/>
  </a>
  <section class="copyright">
    Copyright © 2017 Facebook Inc.
  </section>
</footer>

  </div>

  <div id="fb-root"></div>
  <script src="/js/anchor-links.js"></script>
  <script>
    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
    ga('create', 'UA-41298772-1', 'facebook.github.io');
    ga('send', 'pageview');

    !function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="https://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");

    (function(d, s, id) {
      var js, fjs = d.getElementsByTagName(s)[0];
      if (d.getElementById(id)) return;
      js = d.createElement(s); js.id = id;
      js.src = "//connect.facebook.net/en_US/sdk.js#xfbml=1&version=v2.6&appId=623268441017527";
      fjs.parentNode.insertBefore(js, fjs);
    }(document, 'script', 'facebook-jssdk'));

    docsearch({
      apiKey: '36221914cce388c46d0420343e0bb32e',
      indexName: 'react',
      inputSelector: '#algolia-doc-search'
    });
  </script>
</body>
</html>
